﻿using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace SimpleLibrary
{
    /// <summary>
    /// Interaction logic for SplashScreen.xaml
    /// </summary>
    public partial class SplashScreen : Window
    {
        private readonly DispatcherTimer _startUp = new DispatcherTimer();

        private Mutex _mutex;
        private const String MutexName = "Library";        
        public SplashScreen()
        {
            InitializeComponent();
            _startUp.Interval = new TimeSpan(0, 0, 3);
            _startUp.Tick += startUp_Tick;

            try
            {
                _mutex = Mutex.OpenExisting(MutexName);
                //since it hasn't thrown an exception, then we already have one copy of the app open.
                MessageBox.Show("A copy of Application is already Running.");
                Environment.Exit(0);
            }
            catch
            {
                _mutex = new Mutex(true, MutexName);
                Logger.Init();
            }
        }

        void startUp_Tick(object sender, EventArgs e)
        {
            //Timer tick event to start loading of data and screens.
            DataManager.Instance.Init();
            Thread.Sleep(100);
            ThreadStart uiLoader = () => Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(LoadWindow));
            new Thread(uiLoader).Start();
            _startUp.Stop();
        }

        private void LoadWindow()
        {
            Logger.WriteTrace("Initializing Main Window",TraceLevel.Verbose);
            MainScreen screen = new MainScreen();
            Application.Current.MainWindow = screen;
            Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;

            Logger.WriteTrace("Showing Main Window", TraceLevel.Verbose);
            screen.Show();
            this.Hide();
        }

        #region Loading Animation
        void StartTextAnimations(object sender, RoutedEventArgs e)
        {
            this.titleBlock.TextEffects = new TextEffectCollection();

            Storyboard storyBoardLocation = new Storyboard();

            Storyboard storyBoardRotation = new Storyboard { RepeatBehavior = RepeatBehavior.Forever, AutoReverse = true };

            for (int i = 0; i < this.titleBlock.Text.Length; ++i)
            {

                this.AddTextEffectForCharacter(i);
                this.AddLocationAnimationForCharacter(storyBoardLocation, i);
                this.AddRotationAnimationForCharacter(storyBoardRotation, i);
            }

            Timeline pause = this.FindResource("CharacterRotationPauseAnimation") as Timeline;
            storyBoardRotation.Children.Add(pause);

            storyBoardLocation.Begin(this);
            storyBoardRotation.Begin(this);

            _startUp.Start();
        }

        void AddTextEffectForCharacter(int charIndex)
        {
            TextEffect effect = new TextEffect();

            effect.PositionStart = charIndex;
            effect.PositionCount = 1;

            TransformGroup transGrp = new TransformGroup();
            transGrp.Children.Add(new TranslateTransform());
            transGrp.Children.Add(new RotateTransform());
            effect.Transform = transGrp;

            this.titleBlock.TextEffects.Add(effect);
        }


        void AddLocationAnimationForCharacter(Storyboard storyBoardLocation, int charIndex)
        {
            DoubleAnimation anim = this.FindResource("CharacterLocationAnimation") as DoubleAnimation;

            double offset = anim.Duration.TimeSpan.TotalMilliseconds / 10;
            anim.BeginTime = TimeSpan.FromMilliseconds(offset * charIndex);

            string path = String.Format("TextEffects[{0}].Transform.Children[0].Y", charIndex);
            Storyboard.SetTargetProperty(anim, new PropertyPath(path));

            storyBoardLocation.Children.Add(anim);
        }


        void AddRotationAnimationForCharacter(Storyboard storyBoardRotation, int charIndex)
        {
            DoubleAnimation anim = this.FindResource("CharacterRotationAnimation") as DoubleAnimation;

            double offset = anim.Duration.TimeSpan.TotalMilliseconds / 10;
            anim.BeginTime = TimeSpan.FromMilliseconds(offset * charIndex);

            string path = String.Format("TextEffects[{0}].Transform.Children[1].Angle", charIndex);
            Storyboard.SetTargetProperty(anim, new PropertyPath(path));

            storyBoardRotation.Children.Add(anim);
        }
        #endregion
    }
}
